require 'xcodeproj'

begin
    unless ARGV.size >= 2
        puts "Error: need to pass in project_path and target_name."
        puts "Correct usage: ruby link_and_embed.rb <project_path> <target_name>"
        exit 1
    end
    project_path = ARGV[0]
    target_name = ARGV[1]

    # open xcodeproj
    xcodeproj_path = File.join(project_path, "#{target_name}.xcodeproj")
    unless File.exist?(xcodeproj_path)
        puts "Error: project file not exist - #{xcodeproj_path}"
        exit 1
    end
    project = Xcodeproj::Project.open(xcodeproj_path)

    # get dylibs
    dylibs_path = File.join(project_path, "libs")
    unless Dir.exist?(dylibs_path)
        puts "Warning: Frameworks not exist - #{dylibs_path}"
        exit 0
    end
    dylibs = Dir.glob(File.join(dylibs_path, "*.dylib")) + 
            Dir.glob(File.join(dylibs_path, "*.framework"))
    if dylibs.empty?
        puts "Warning: not find any .dylib or .framework file."
        exit 0
    end

    # find taget
    target = project.targets.find { |t| t.name == target_name }
    frameworks_group = project.groups.find { |g| g.display_name == 'Frameworks' }
    unless frameworks_group
        frameworks_group = project.new_group('Frameworks')
    end

    embed_libraries_phase = target.build_phases.find { |p| p.display_name == 'Embed Libraries' }
    unless embed_libraries_phase
        embed_libraries_phase = target.new_copy_files_build_phase('Embed Libraries')
        embed_libraries_phase.symbol_dst_subfolder_spec = :frameworks
        embed_libraries_phase.dst_path = ''
    end

    frameworks_group.files.each do |file_ref|
        embed_libraries_phase.files.each do |build_file|
            if build_file.file_ref == file_ref
                embed_libraries_phase.remove_build_file(build_file)
            end
        end
        file_ref.remove_from_project
    end

    dylibs.each do |dylib_path|
        puts "processing: #{dylib_path}"
        dylib_name = File.basename(dylib_path)
        file_ref = frameworks_group.files.find { |f| f.path == dylib_name }
        unless file_ref
            file_ref = frameworks_group.new_file(dylib_path)
            puts "File reference added: #{dylib_name}"
        end

        if target.frameworks_build_phase.files_references.include?(file_ref)
            target.frameworks_build_phase.remove_file_reference(file_ref)
            puts "File removed from Link Phase: #{dylib_name}"
        end

        unless embed_libraries_phase.files_references.include?(file_ref)
            build_file = embed_libraries_phase.add_file_reference(file_ref, true)
            build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy', 'RemoveHeadersOnCopy'] }
            puts "File add to Embed Libraries: #{dylib_name}"
        end
    end

    puts "project saving..."
    project.save
    puts "Script execution successful completion."
    exit 0
rescue => e
  puts "Error: #{e.message}"
  puts "Message:"
  puts e.backtrace.join("\n")
  exit 1
end